Skip to content

feat(benchmark): per-run output paths and cluster membership - #24

Merged
StressTestor merged 1 commit into
mainfrom
feat/benchmark-out-only
Jul 29, 2026
Merged

feat(benchmark): per-run output paths and cluster membership#24
StressTestor merged 1 commit into
mainfrom
feat/benchmark-out-only

Conversation

@StressTestor

Copy link
Copy Markdown
Owner

Every benchmark run wrote data/benchmark-results.json. Two runs in a row therefore left only the second one's numbers on disk.

That already cost a run: a local nomic-vs-embeddinggemma comparison was overwritten by a hosted one started afterwards, leaving only console scrollback. Ten minutes of embedding, gone to starting the next comparison.

--out <path>

Gives a run its own file. Parent directories are created. An empty or directory-shaped value throws rather than falling back to the default, since that fallback is exactly the overwrite being avoided.

clusterMembership

Results now record which items landed in which cluster, per model per threshold.

Cluster counts cannot answer the question the benchmark exists to answer. A model that finds more clusters is either catching duplicates the incumbent misses or chaining unrelated items together, and the counts look identical in both cases. Membership is otherwise only recoverable by re-embedding the whole corpus.

It is what settled the question for embeddinggemma: of the 13 clusters it found that nomic missed, 11 were real duplicates and 2 were recurring dependabot PRs. That is unreadable from 13.

440 tests, lint and typecheck clean.

Every benchmark run wrote data/benchmark-results.json, so running a second
comparison silently destroyed the first one's numbers. That already cost a
local nomic-vs-embeddinggemma run: the hosted comparison started afterwards
and overwrote it, leaving only console scrollback.

`--out <path>` gives a run its own file. An empty or directory-shaped value
throws instead of falling back to the default, since that fallback is exactly
the overwrite being avoided. Parent directories are created.

Results now also record `clusterMembership` per model per threshold. Cluster
counts alone cannot answer the question the benchmark exists to answer: a
model that finds more clusters is either catching duplicates the incumbent
misses or chaining unrelated items, and the counts look identical either way.
Membership can only otherwise be recovered by re-embedding the whole corpus.

Also drops the stale caveat on starmap `createdAt` now that star-map's
importer patch is open as PR #11.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6550e8768e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/benchmark.ts
items: c.items.map((item) => item.number),
}));
baseStore.close();
clusterMembership.push({ model: baseline.model, threshold: t, clusters: baseSimplified });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude stale database rows from cluster membership

When a model database already exists from an earlier run and the repository's fetched corpus has since changed, getAllItems(repoFull) includes rows that were not fetched in this run because runBenchmarkForModel only upserts and never removes them. This newly serialized membership can therefore list deleted or page-limit-evicted items and disagree with clustersByThreshold, which was computed using the current allItems; clear obsolete rows or restrict membership clustering to IDs from the current fetch.

Useful? React with 👍 / 👎.

Comment thread src/benchmark.ts
};

const outPath = resolve(process.cwd(), "data", "benchmark-results.json");
const outPath = resolveBenchmarkOutPath(opts.out);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate the output path before running the benchmark

When --out is empty, directory-shaped, or otherwise invalid, this validation is not reached until after every model has been embedded and all clustering has completed. A multi-hour run then fails without writing its JSON—the exact data loss this option is intended to prevent—so resolve and syntactically validate the path before fetching or embedding begins.

Useful? React with 👍 / 👎.

@StressTestor
StressTestor merged commit 124491c into main Jul 29, 2026
2 checks passed
@StressTestor
StressTestor deleted the feat/benchmark-out-only branch July 29, 2026 16:50
@StressTestor
StressTestor restored the feat/benchmark-out-only branch July 29, 2026 16:51
@StressTestor
StressTestor deleted the feat/benchmark-out-only branch July 29, 2026 16:52
@StressTestor StressTestor mentioned this pull request Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant